#include <linux/types.h>
#include <linux/ipc.h>
#include <linux/sem.h>
#include <stdio.h>
#include <stdlib.h>

static int nsems;
static int semflg;
static int semid;
int errno = 0;

/*
union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short* array;
}arg;
*/

int main(void)
{
    union semun arg;
    struct sembuf sops[2];//要用到两个信号量，所以要定义两个操作数组
    int rslt;
    unsigned short argarray[80];
    arg.array = argarray;
    semid = semget(IPC_PRIVATE, 2, 0666);
    if (semid < 0)
    {
        printf("semget failed error: %d\n", errno);
        exit(0);
    }

    //获取0th信号量的原始值
    rslt = semctl(semid, 0, GETVAL);
    printf("val = %d\n", rslt);
    //初始化0th信号量，然后再读取，检查初始化有没有成功
    arg.val = 1; //同一时间只允许一个占用者
    semctl(semid, 0, SETVAL, arg);
    rslt = semctl(semid, 0, GETVAL);
    printf("val = %d\n", rslt);

    sops[0].sem_num = 0;
    sops[0].sem_op = -1;
    sops[0].sem_flg = 0;
    sops[1].sem_num = 1;
    sops[1].sem_op = 1;
    sops[1].sem_flg = 0;

    rslt = semop(semid, sops, 1); //申请0th信号量，尝试锁定
    if (rslt < 0)
    {
        printf("semop failed errno: %d\n", errno);
        exit(0);
    }


    //可以在这里对资源进行锁定
    sops[0].sem_op = 1;
    semop(semid, sops, 1);//释放0th信号量
    rslt = semctl(semid, 0, GETVAL);
    printf("val = %d\n", rslt);
    rslt = semctl(semid, 0, GETALL, arg);
    if (rslt < 0)
    {
        printf("semctl failed errno: %d\n", errno);
        exit(0);
    }
    printf("val1: %d val2: %d\n", (unsigned int)argarray[0], (unsigned int)argarray[1]);
    if (semctl(semid, 1, IPC_RMID) == -1)
    {
        perror("semctl faulure while clearing reason");
    }

    return 0;
}
